package nio.demo;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * @Author: admin
 * @Description:
 * @Date: 2018/11/12 10:18
 */

public class NioSocketServer {
    private static Selector selector;
    private static ServerSocketChannel serverSocketChannel;
    private static ByteBuffer buffer = ByteBuffer.allocate(1024);
    public static void main(String[] args) {
        try {
            // 创建一个selector
            selector=Selector.open();
            // 初始化TCP连接监听通道
            serverSocketChannel=ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);
            serverSocketChannel.bind(new InetSocketAddress(9999));
            //serverSocketChannel.socket().bind(new InetSocketAddress(9999));
            // 注册到selector（监听其ACCEPT事件）
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

            while (true){
                System.out.println("监听事件");
                selector.select();//阻塞，直到有监听的事件发生
                System.out.println("事件发生");
                Iterator<SelectionKey> selectionKeys=selector.selectedKeys().iterator();
                System.out.println("-------");
                // 通过迭代器依次访问select出来的Channel事件
                while (selectionKeys.hasNext()){
                    SelectionKey key=selectionKeys.next();
                    System.out.println(key+"\t");
                    if(key.isAcceptable()){ // 有连接可以接受
                        System.out.println(key+"\tisAcceptable "+key.isAcceptable());
                        ServerSocketChannel ssc=(ServerSocketChannel)key.channel();
                        SocketChannel socketChannel=ssc.accept();
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector,SelectionKey.OP_READ);
                    }else if(key.isConnectable()){
                        System.out.println(key+"\tisConnectable "+key.isConnectable());
                    }else if(key.isReadable()){// 有数据可以读取
                        System.out.println(key+"\tisReadable "+key.isReadable());
                        SocketChannel socketChannel=(SocketChannel)key.channel();
                        int readLen=0;
                        buffer.clear();
                        StringBuilder sb=new StringBuilder();
                        while ((readLen=socketChannel.read(buffer))>0){
                            // 切换到读取模式
                            buffer.flip();
                            byte[] temp=new byte[readLen];
                            buffer.get(temp,0,readLen);
                            sb.append(new String(temp));
                            buffer.clear();
                        }
                        System.out.println("接收数据："+sb.toString());
                        if(sb.toString().equals("exit"))
                            socketChannel.close();
                        else
//                        buffer.clear();
//                        buffer.put("hello client".getBytes());
//                        buffer.flip();
//                        while (buffer.hasRemaining()){
//                            socketChannel.write(buffer);
//                        }
                       socketChannel.write(ByteBuffer.wrap("hello client".getBytes()));
                    }else if(key.isWritable()){
                    }
                    selectionKeys.remove();
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
